package com.wgo.bpot.server.persist;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import com.wgo.bpot.common.transport.servicefacade.UniqueValueFactory;
import com.wgo.bpot.domain.common.CommandHistory;
import com.wgo.bpot.wiring.common.DomainModelConvention;


public interface PersistService<S> {
	public void createSchema();
	public UniqueValueFactory getUniqueValueFactory();
	public CommandHistory createCommandHistoryEntry();
	public void setDomainModelConvention(DomainModelConvention<S> domainModelConvention);
	
	public DomainModelConvention<S> getDomainModelConvention();

	/**
	 * @param type The api-class of the wanted object
	 */
	public <T extends S> Collection<T> find(Class<T> type, int linkDepth);
	/**
	 * This method will return a single element
	 * @param type The api-class of the wanted object
	 */
	public <T extends S> S find(Class<T> type, String fieldName, String fieldValue, int linkDepth);

	/**
	 * @param <T>
	 * @param type The api-class of the wanted object
	 * @param id
	 * @return A clean object that is ready to be sent to the client.
	 */
	public <T extends S> S getInstance(Class<T> type, Serializable id , int linkDepth);
	
	/**
	 * @param <T>
	 * @param type The api-class of the wanted object
	 * @param id
	 * @return An instance of the concept. NOTE: this instanse could contain 
	 * server-spesific code, and should not be sent to the client.
	 */
	public <T extends S> T getDbInstance(Class<T> type, Serializable id);

	/**
	 * @param instanceToBeSaved
	 */
	public <T extends S> void save(T instanceToBeSaved);

	/**
	 * @param instanceToBeSaved
	 * @return An instance of the concept. NOTE: this instanse could contain 
	 * server-spesific code, and should not be sent to the client.
	 */
	public void saveOrUpdate(Object instanceToBeSaved);

	/**
	 * @param instanceToBeSaved
	 * @return An instance of the concept. NOTE: this instanse could contain 
	 * server-spesific code, and should not be sent to the client.
	 */
	public <T extends S> T newInstance (Class<T> apiType ) throws InstantiationException, IllegalAccessException ;

	public void startTransaction();
	public boolean isTransactionActive();
	public void commitTransaction();
	public void rollbackTransaction();
	public <T extends S> List<CommandHistory> retrieveCommandHistory(Class<T> conceptType, Long dbId);
	public Object openSession();
	public void closeSession();
}
